﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;

namespace YJKFilterExpanded.YJKFilterExpanded
{
	public class FilterManager
	{
		public FilterManager(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
		}

		public void YJKFilterExpanded()
		{
			if (this.m_Revit.Application.ActiveUIDocument.Selection.GetElementIds().Count == 0 && !this.SelectElement())
			{
				return;
			}
			List<CategoryItemData> list = new List<CategoryItemData>();
			if (!this.InitializeCategoryList(ref list))
			{
				return;
			}
			list.Sort(new Comparison<CategoryItemData>(CategoryItemData.CategoryItemDataCompare));
			new ExtendedFilterForm(this, list).ShowDialog();
		}

		private bool SelectElement()
		{
			IList<Element> source = null;
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			RevitVersionFuncs.ClearSelection(selection);
			try
			{
				source = selection.PickElementsByRectangle("目前选择集为空，先选取区域创建选择集");
			}
			catch (Exception)
			{
				return false;
			}
			RevitVersionFuncs.SetSelection(selection, source.ToList<Element>());
			return true;
		}

		private bool InitializeCategoryList(ref List<CategoryItemData> selectCategoryList)
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			ICollection<ElementId> elementIds = this.m_Revit.Application.ActiveUIDocument.Selection.GetElementIds();
			if (elementIds.Count == 0)
			{
				YJKMessageBox.Show("当前没有选择实体，请先选择实体后运行命令。");
				return false;
			}
			foreach (ElementId elementId in elementIds)
			{
				try
				{
					Element element = document.GetElement(elementId);
					if (element != null)
					{
						if (element.Category != null)
						{
							if (!(null == element.GetType()))
							{
								Category category = element.Category;
								int num = selectCategoryList.FindIndex((CategoryItemData value) => value.TheCategory.Id.Equals(category.Id));
								if (-1 == num)
								{
									List<FamilyItemData> familyItemList = new List<FamilyItemData>();
									CategoryItemData categoryItemData = new CategoryItemData(category, familyItemList);
									categoryItemData.AddElement(document, element);
									selectCategoryList.Add(categoryItemData);
								}
								else
								{
									selectCategoryList[num].AddElement(document, element);
								}
							}
						}
					}
				}
				catch (Exception ex)
				{
					string message = ex.Message;
				}
			}
			return true;
		}

		public void GroupingByProperties(List<Element> elements, List<PropertyInfo> propertiesInfo, ref List<GroupingDataByProperty> grouingData)
		{
			using (List<PropertyInfo>.Enumerator enumerator = propertiesInfo.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					PropertyInfo proInfo = enumerator.Current;
					if (proInfo.Checked)
					{
						foreach (Element element in elements)
						{
							Parameter parameter = element.GetParameter(proInfo.TheName);
							if (parameter != null)
							{
								string value = "";
								if ((int)parameter.StorageType == 3)
								{
									value = parameter.AsString();
								}
								else
								{
									value = parameter.AsValueString();
								}
								if (value == null)
								{
									value = "";
								}
								int num = grouingData.FindIndex((GroupingDataByProperty item) => item.TheName.CompareTo(proInfo.TheName) == 0 && item.TheValue.CompareTo(value) == 0);
								if (-1 == num)
								{
									List<Element> list = new List<Element>();
									list.Add(element);
									GroupingDataByProperty item2 = new GroupingDataByProperty(proInfo.TheName, value, list);
									grouingData.Add(item2);
								}
								else
								{
									grouingData[num].Elements.Add(element);
								}
							}
						}
					}
				}
			}
		}

		public void ShowElement(List<Element> elements, bool zoomToElements)
		{
			this.HighlightElements(elements);
			if (zoomToElements)
			{
				ElementSet elementSet = new ElementSet();
				foreach (Element element in elements)
				{
					elementSet.Insert(element);
				}
				if (elementSet.Size > 0)
				{
					this.m_Revit.Application.ActiveUIDocument.ShowElements(elementSet);
				}
			}
		}

		private void HighlightElements(List<Element> elements)
		{
			RevitVersionFuncs.SetSelection(this.m_Revit.Application.ActiveUIDocument.Selection, elements);
		}

		private ExternalCommandData m_Revit;
	}
}
